// EventTestApp1.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>

#include <string>

#include "../Common/CppThread.h"
#include "../Common/SyncEvent.h"

//#include "ShareRestrictedSD.h"
#define BUF_SIZE 256
//TCHAR szName[] = TEXT("Global\\MyFileMappingObject");// CreateFileMapping failed, error code is 5
//TCHAR szName[] = TEXT("Local\\MyFileMappingObject");//CreateFileMapping ok
TCHAR szName[] = TEXT("MyFileMappingObject");
TCHAR szMsg[] = TEXT("Message from first process.");

class ReceiveThread :public CppThread
{
public:
    ReceiveThread(void* shareMem, SyncEvent* event)
    {
        _shareMem = shareMem;
        _syncEvent = event;
    }
protected:
    virtual void run()
    {
        while (!IsDone())
        {
            _syncEvent->Wait();
            std::cout << (char*)_shareMem;
        }
    }

private:
    void* _shareMem = nullptr;
    SyncEvent* _syncEvent = nullptr;

};


int main()
{
    SyncEvent event1("App1Event");
    SyncEvent event2("App2Event");

    

    HANDLE hMapFile;
    LPCTSTR pBuf;


    //CShareRestrictedSD ShareRestrictedSD;
    hMapFile = CreateFileMapping(
        INVALID_HANDLE_VALUE,    // use paging file
        /*ShareRestrictedSD.GetSA()*/NULL,                    // default security
        PAGE_READWRITE,          // read/write access
        0,                       // maximum object size (high-order DWORD)
        BUF_SIZE,                // maximum object size (low-order DWORD)
        szName);                 // name of mapping object

    if (hMapFile == NULL)
    {
        _tprintf(TEXT("Could not create file mapping object (%d).\n"),
            GetLastError());
        return 1;
    }
    pBuf = (LPTSTR)MapViewOfFile(hMapFile,   // handle to map object
        FILE_MAP_ALL_ACCESS, // read/write permission
        0,
        0,
        BUF_SIZE);

    if (pBuf == NULL)
    {
        _tprintf(TEXT("Could not map view of file (%d).\n"),
            GetLastError());

        CloseHandle(hMapFile);

        return 1;
    }

    ReceiveThread recThread((void*)pBuf, &event1);
    recThread.start();
    while (true)
    {
        std::string tmpStr;
        std::cout << "Input command:";
        std::cin >> tmpStr;
        if (tmpStr == "exit") break;

        CopyMemory((PVOID)pBuf, tmpStr.c_str(), tmpStr.size());
        event2.Set();
    }

    recThread.SetDone();
    event1.Set();
    recThread.join();

    CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
    //_getch();

    UnmapViewOfFile(pBuf);

    CloseHandle(hMapFile);


    return 0;
    //std::cout << "Hello World!\n";
}

// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
// Debug program: F5 or Debug > Start Debugging menu

// Tips for Getting Started: 
//   1. Use the Solution Explorer window to add/manage files
//   2. Use the Team Explorer window to connect to source control
//   3. Use the Output window to see build output and other messages
//   4. Use the Error List window to view errors
//   5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
//   6. In the future, to open this project again, go to File > Open > Project and select the .sln file
